package com.sap.sap_mangers.controller;

import com.sap.sap_mangers.Vo.ShareVo.SapShareVo;
import com.sap.sap_mangers.dto.share.FailToPassTheAudit;
import com.sap.sap_mangers.dto.share.ModifyFile;
import com.sap.sap_mangers.dto.share.PassTheAudit;
import com.sap.sap_mangers.dto.share.UploadFile;
import com.sap.sap_mangers.pojo.SapShare;
import com.sap.sap_mangers.pojo.SapShareType;
import com.sap.sap_mangers.service.CacheService;
import com.sap.sap_mangers.service.ShareService;
import com.sap.sap_mangers.service.UserService;
import com.sap.sap_mangers.until.JwtUtil;
import com.sap.sap_mangers.until.SimpleJson;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

/**
 * @author 阿东
 * @date 2022/9/11 [19:07]
 */
@RestController
@RequestMapping("/Share")
public class ShareController {
    @Autowired
    private ShareService shareService;
    @Autowired
    private UserService userService;

    @Autowired
    private CacheService cacheService;

    @PreAuthorize("hasAuthority('正式成员')")
    @PostMapping("/uploadFile")
    public SimpleJson uploadFile(HttpServletRequest request) {
        HttpRequestParam httpRequestParam = new HttpRequestParam();
        MultipartHttpServletRequest params = ((MultipartHttpServletRequest) request);
        List<MultipartFile> file = ((MultipartHttpServletRequest) request).getFiles("file");

        String topic = params.getParameter("topic");
        String url = params.getParameter("url");
        String type = params.getParameter("type");
        int intFileType;
        if (topic.isEmpty() || type.isEmpty()) {
            return new SimpleJson(1, "参数不能为空");
        }
        if (url != null && !file.isEmpty()) {
            return new SimpleJson(1, "只能选择一种方式传递资料");
        } else if (url != null) {
            //纯网址的方式分享
            intFileType = 0;
        } else if (!file.isEmpty()) {
            //文件
            if (file.size() != 1) {
                return new SimpleJson(1, "仅允许上传1个文件");
            }
            intFileType = 1;
        } else {
            return new SimpleJson(1, "没传递任何资料");
        }
        List<SapShareType> sapShareType = shareService.getSapShareType();
        boolean check = false;
        for (SapShareType shareType : sapShareType) {
            if (shareType.getShareTypeId().equals(Integer.valueOf(type))) {
                check = true;
            }
        }
        if (!check) {
            return new SimpleJson(1, "type参数错误");
        }
        httpRequestParam.setShareTopic(topic);
        //不判断直接注入在file字段没传参数时.get()直接报错
        if (intFileType == 1) {
            httpRequestParam.setShareFile(file.get(0));
        }
        httpRequestParam.setShareUrl(url);
        httpRequestParam.setShareType(Integer.valueOf(type));
        httpRequestParam.setShareFileType(intFileType);
        UploadFile uploadFile = new UploadFile(
                httpRequestParam.getShareTopic(),
                httpRequestParam.getShareFile(),
                httpRequestParam.getShareUrl(),
                httpRequestParam.getShareType(),
                httpRequestParam.getShareFileType());
        if (httpRequestParam.getShareFileType() == 1) {
            if (!Objects.requireNonNull(httpRequestParam.getShareFile().getOriginalFilename()).endsWith(".md")) {
                return new SimpleJson(1, "仅允许上传markdown文件,其他文件请上传阿里/百度云上传链接！");
            }
            return shareService.uploadFile(uploadFile);
        } else if (httpRequestParam.getShareFileType() == 0) {
            return shareService.addFileUrl(uploadFile);
        } else {
            return new SimpleJson(1, "参数错误");
        }

    }

    /**
     * (管理层)获取未审核的上传记录
     *
     * @return 未审核的资料上传记录
     */
    @PreAuthorize("hasAuthority('旧管理员')")
    @GetMapping("/getSapShareThatNotNotBeAudited")
    public SimpleJson getSapShareThatNotNotBeAudited() {
        //是否问管理层成员
        if (userService.getUserByUserName(JwtUtil.getUserForToken()).getRole() > 9) {
            return new SimpleJson(1, "权限不足");
        }
        return new SimpleJson(0, "成功", shareService.getSapShareThatNotNotBeAudited());
    }

    @PreAuthorize("hasAuthority('正式成员')")
    @GetMapping("/setPrivate")
    public SimpleJson setPrivate(@RequestParam("id") Integer id, @RequestParam("value") Integer value) {
        boolean check = belongsToYouOrNot(id);
        if (!check) {
            return new SimpleJson(1, "只能更改自己上传的资料的状态");
        }
        if (value < 0 || value > 1) {
            return new SimpleJson(1, "value不合法");
        }
        try {
            shareService.updateShared(id, value);
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(1, "SQL执行出错");
        }
        return SimpleJson.SUCCESS;
    }

    /**
     * 判断操作的资料ID是否属于自己上传的
     *
     * @param id 资料id
     * @return boolean
     */
    private boolean belongsToYouOrNot(Integer id) {
        List<SapShare> sapShare = shareService.getSapShare(JwtUtil.getUserForToken(), null);
        boolean check = false;
        for (SapShare share : sapShare) {
            if (share.getShareId().equals(id)) {
                check = true;
                break;
            }
        }
        return check;
    }

    @PreAuthorize("hasAuthority('正式成员')")
    @DeleteMapping("/deleteFile")
    public SimpleJson deleteFile(@RequestParam("id") Integer id) {
        SapShare shareMessageById = shareService.getShareMessageById(id);
        if (shareMessageById == null) {
            return new SimpleJson(1, "信息为空");
        }
        if (!JwtUtil.getUserForToken().equals(shareMessageById.getShareUsername())) {
            return new SimpleJson(1, "只能更改自己上传的资料的状态");
        }
        if (shareMessageById.getShareApproval() != 1) {
            return new SimpleJson(1, "该资料信息无法通过该方法更改");
        }
        try {
            return shareService.deleteFile(id);
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(1, "SQL执行出错");
        }
    }

    @PreAuthorize("hasAuthority('游客')")
    @GetMapping("/downLoadFile")
    public SimpleJson downLoadFile(@RequestParam("id") Integer id) {
        try {
            shareService.updateDownloadFile(id);
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(1, "SQL执行出错");
        }
        return SimpleJson.SUCCESS;
    }

    @PreAuthorize("hasAuthority('游客')")
    @GetMapping("/getShareMessageForUser")
    public SimpleJson getShareMessageForUser() {
        List<SapShareVo> sapShare = shareService.getSapShareForUser(JwtUtil.getUserForToken());
        for (SapShareVo sapShareVo : sapShare) {
            sapShareVo.setHeader(cacheService.getHeaderCache(cacheService.getHeaderCacheMap(),JwtUtil.getUserForToken()));
        }
        return new SimpleJson(sapShare);
    }

    /**
     * (管理层)获取所有上传记录
     *
     * @return 所有上传记录
     */
    @PreAuthorize("hasAuthority('旧管理员')")
    @GetMapping("/getAllSapShare")
    public SimpleJson getAllSapShare() {
        if (userService.getUserByUserName(JwtUtil.getUserForToken()).getRole() > 9) {
            return new SimpleJson(1, "权限不足");
        }
        return new SimpleJson(0, "成功", shareService.getAllSapShare());
    }

    /**
     * 获取可共享的资料 (按分享方式和资料类型分类嵌套)
     *
     * @return 可共享的资料
     */
    @PreAuthorize("hasAuthority('游客')")
    @GetMapping("/getApprovedShareRecord")
    public SimpleJson getApprovedShareRecord() {
        return new SimpleJson(0, "成功", shareService.getApprovedShareRecord());
    }

    @PreAuthorize("hasAuthority('游客')")
    @GetMapping("/getShareType")
    public SimpleJson getShareType() {
        return new SimpleJson(shareService.getSapShareType());
    }

    /**
     * 修改资料/文件
     *
     * @param topic      分享内容标题
     * @param file       文件
     * @param url        网址
     * @param typeId     资料类型对应的编号
     * @param oldShareId 原资料/文件ID
     * @return JSON
     */
    @PreAuthorize("hasAuthority('正式成员')")
    @PostMapping("/modifyFile")
    public SimpleJson modifyFile(@RequestParam(value = "topic") String topic,
                                 @RequestParam(value = "file", required = false) MultipartFile file,
                                 @RequestParam(value = "url", required = false) String url,
                                 @RequestParam(value = "typeId") Integer typeId,
                                 @RequestParam(value = "oldShareId") Integer oldShareId) {
        if (topic == null || typeId == null || oldShareId == null) {
            return new SimpleJson(1, "参数异常，没填写参数");
        }
        //分享方式
        int fileType;
        if (url != null && file != null) {
            return new SimpleJson(1, "参数异常，只能选择一种方式传递资料");
        } else if (url != null) {
            fileType = 0;
        } else if (file != null) {
            fileType = 1;
        } else {
            return new SimpleJson(1, "参数异常，没传递任何资料");
        }
        //判断资料类型是否合理
        SapShareType type = shareService.getSapShareTypeById(typeId);
        if (type == null) {
            return new SimpleJson(1, "参数异常，没有对应的资料类型");
        }
        //判断原资料分享记录是否存在且为通过状态
        SapShare oldShare = shareService.getShareMessageById(oldShareId);
        if (oldShare == null) {
            return new SimpleJson(2, "参数异常，未找到旧版本记录");
        } else if (oldShare.getShareApproval() != 1) {
            return new SimpleJson(2, "参数异常，旧版本记录不在通过状态");
        } else if (!JwtUtil.getUserForToken().equals(oldShare.getShareUsername())) {
            return new SimpleJson(2, "无法操作别人的数据");
        }
        ModifyFile modifyFile = new ModifyFile(topic, file, url, typeId, fileType, oldShareId);

        if (fileType == 1) {
            if (!Objects.requireNonNull(file.getOriginalFilename()).endsWith(".md")) {
                return new SimpleJson(3, "参数异常，仅允许上传markdown文件,其他文件请上传阿里/百度云后上传链接！");
            }
            //文件上传cos后将数据添加进数据库(同时添加版本更替表数据)
            return shareService.modifyFile(modifyFile);
        } else {
            //纯网址资料处理
            return shareService.addFileUrlWhenModify(modifyFile);
        }
    }

    /**
     * 审核驳回(不通过)
     * <p>
     * 只有管理层能使用，将没通过的资料上传记录驳回(不通过)
     *
     * @param fail 驳回的记录编号和驳回原因
     * @return JSON
     */
    @PreAuthorize("hasAuthority('旧管理员')")
    @PostMapping("/failedToPassTheAudit")
    public SimpleJson failedToPassTheAudit(@RequestBody FailToPassTheAudit fail) {
        Integer shareId = fail.getShareId();
        String reason = fail.getReason();
        if (shareId == null || reason == null || "".equals(reason.trim())) {
            return new SimpleJson(5, "未填写参数");
        }
        try {
            return shareService.failedToPassTheAudit(shareId, reason);
        } catch (Exception e) {
            return new SimpleJson(4, "事务异常");
        }
    }

    @Data
    static
    class HttpRequestParam {
        /**
         * 分享资料的标题
         */
        private String shareTopic;
        /**
         * 分享资料的文件
         */
        private MultipartFile shareFile;
        /**
         * 分享资料的第三方平台URL
         */
        private String shareUrl;
        /**
         * 分享资料的类型(0：第三方平台，1：腾讯云对象储存)
         */
        private Integer shareFileType;
        /**
         * 资料类型
         */
        private Integer shareType;
    }

    /**
     * 审核通过
     * <p>
     * 只有管理层能使用，将资料分享上传记录通过，使其他人能访问
     * 事务支持
     *
     * @param pass 资料分享记录ID
     * @return JSON
     */
    @PreAuthorize("hasAuthority('旧管理员')")
    @PostMapping("/passTheAudit")
    public SimpleJson passTheAudit(@RequestBody PassTheAudit pass) {
        Integer shareId = pass.getShareId();
        if (shareId == null) {
            return new SimpleJson(5, "未填写参数");
        }
        try {
            return shareService.passTheAudit(shareId);
        } catch (Exception e) {
            return new SimpleJson(4, "事务异常");
        }
    }

    /**
     * 获取可共享的资料中下载/访问次数前九名的数据
     *
     * @return 可共享的下载量前十的资料
     */
    @PreAuthorize("hasAuthority('游客')")
    @GetMapping("/getApprovalTopTen")
    public SimpleJson getApprovalTopTen() {
        try {
            List<SapShareVo> approvalTopTen = shareService.getApprovalTopTen();
            return new SimpleJson(0, "成功", approvalTopTen);
        } catch (Exception e) {
            e.printStackTrace();
            return new SimpleJson(1, "服务器异常");
        }
    }
}
